Resolves: #i124338# assure sorted mark containers...

when updating <SwIndex> instances due to inserted characters

(cherry picked from commit 770c0e6b910129710b4be5cb9e9bae39bfa6bd5a)

Conflicts:
	sw/source/core/bastyp/index.cxx
	sw/source/core/crsr/bookmrk.cxx
	sw/source/core/doc/docbm.cxx
	sw/source/core/inc/bookmrk.hxx
	sw/source/core/inc/crossrefbookmark.hxx

Change-Id: Ie4531c3b33aff0a7f3d139ee81a21c3823474f84
diff --git a/sw/inc/IDocumentMarkAccess.hxx b/sw/inc/IDocumentMarkAccess.hxx
index 784b45f..8d59cbf 100644
--- a/sw/inc/IDocumentMarkAccess.hxx
+++ b/sw/inc/IDocumentMarkAccess.hxx
@@ -194,6 +194,8 @@
        */
        virtual void clearAllMarks() =0;

        virtual void assureSortedMarkContainers() const = 0;

        /** returns a STL-like random access iterator to the begin of the sequence of marks.
        */
        virtual const_iterator_t getAllMarksBegin() const =0;
diff --git a/sw/source/core/bastyp/index.cxx b/sw/source/core/bastyp/index.cxx
index 120d119..4f3f045 100644
--- a/sw/source/core/bastyp/index.cxx
+++ b/sw/source/core/bastyp/index.cxx
@@ -223,8 +223,11 @@
    assert(!m_pFirst && !m_pLast); // There are still indices registered
}

void SwIndexReg::Update( SwIndex const & rIdx, const sal_Int32 nDiff,
    const bool bNeg, const bool /* argument is only used in derived class*/ )
void SwIndexReg::Update(
    SwIndex const & rIdx,
    const sal_Int32 nDiff,
    const bool bNeg,
    const bool /* argument is only used in derived class*/ )
{
    SwIndex* pStt = const_cast<SwIndex*>(&rIdx);
    const sal_Int32 nNewVal = rIdx.m_nIndex;
diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index f09895a..1fb0b05 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -64,31 +64,32 @@
        const sal_Unicode aStartMark,
        const sal_Unicode aEndMark)
    {
        SwPosition& rStart = pField->GetMarkStart();
        SwPosition& rEnd = pField->GetMarkEnd();
        io_pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_UI_REPLACE, NULL);

        SwTxtNode const*const pStartTxtNode =
            rStart.nNode.GetNode().GetTxtNode();
        SwTxtNode const*const pEndTxtNode = rEnd.nNode.GetNode().GetTxtNode();
        SwPosition rStart = pField->GetMarkStart();
        SwTxtNode const*const pStartTxtNode = rStart.nNode.GetNode().GetTxtNode();
        const sal_Unicode ch_start = ( rStart.nContent.GetIndex() >= pStartTxtNode->GetTxt().getLength() ) ? 0 :
            pStartTxtNode->GetTxt()[rStart.nContent.GetIndex()];
        if( ( ch_start != aStartMark ) && ( aEndMark != CH_TXT_ATR_FORMELEMENT ) )
        {
            SwPaM aStartPaM(rStart);
            io_pDoc->InsertString(aStartPaM, OUString(aStartMark));
            rStart.nContent--;
            pField->SetMarkStartPos( rStart );
        }

        SwPosition& rEnd = pField->GetMarkEnd();
        SwTxtNode const*const pEndTxtNode = rEnd.nNode.GetNode().GetTxtNode();
        const sal_Int32 nEndPos = ( rEnd == rStart ||  rEnd.nContent.GetIndex() == 0 ) ?
            rEnd.nContent.GetIndex() : rEnd.nContent.GetIndex() - 1;
        const sal_Unicode ch_end = nEndPos >= pEndTxtNode->GetTxt().getLength() ? 0 : pEndTxtNode->GetTxt()[nEndPos];
        SwPaM aStartPaM(rStart);
        SwPaM aEndPaM(rEnd);

        io_pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_UI_REPLACE, NULL);
        if( ( ch_start != aStartMark ) && ( aEndMark != CH_TXT_ATR_FORMELEMENT ) )
        {
            io_pDoc->InsertString(aStartPaM, OUString(aStartMark));
            rStart.nContent--;
        }
        if ( aEndMark && ( ch_end != aEndMark ) )
        {
            SwPaM aEndPaM(rEnd);
            io_pDoc->InsertString(aEndPaM, OUString(aEndMark));
            rEnd.nContent++;
        }

        io_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_UI_REPLACE, NULL);
    };

@@ -97,31 +98,33 @@
        const sal_Unicode aStartMark,
        const sal_Unicode aEndMark)
    {
        SwPosition& rStart = pField->GetMarkStart();
        SwPosition& rEnd = pField->GetMarkEnd();
        SwTxtNode const*const pStartTxtNode =
            rStart.nNode.GetNode().GetTxtNode();
        SwTxtNode const*const pEndTxtNode = rEnd.nNode.GetNode().GetTxtNode();
        io_pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_UI_REPLACE, NULL);

        const SwPosition& rStart = pField->GetMarkStart();
        SwTxtNode const*const pStartTxtNode = rStart.nNode.GetNode().GetTxtNode();
        const sal_Unicode ch_start =
            pStartTxtNode->GetTxt()[rStart.nContent.GetIndex()];
        const sal_Int32 nEndPos = ( rEnd == rStart ||  rEnd.nContent.GetIndex() == 0 ) ?
            rEnd.nContent.GetIndex() : rEnd.nContent.GetIndex() - 1;
        const sal_Unicode ch_end = pEndTxtNode->GetTxt()[nEndPos];
        SwPaM aStartPaM(rStart);
        SwPaM aEndPaM(rEnd);
        io_pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_UI_REPLACE, NULL);

        if( ch_start == aStartMark )
        {
            SwPaM aStart(rStart, rStart);
            aStart.End()->nContent++;
            io_pDoc->DeleteRange(aStart);
        }

        const SwPosition& rEnd = pField->GetMarkEnd();
        SwTxtNode const*const pEndTxtNode = rEnd.nNode.GetNode().GetTxtNode();
        const sal_Int32 nEndPos = ( rEnd == rStart ||  rEnd.nContent.GetIndex() == 0 )
                                   ? rEnd.nContent.GetIndex()
                                   : rEnd.nContent.GetIndex() - 1;
        const sal_Unicode ch_end = pEndTxtNode->GetTxt()[nEndPos];
        if ( ch_end == aEndMark )
        {
            SwPaM aEnd(rEnd, rEnd);
            aEnd.Start()->nContent--;
            io_pDoc->DeleteRange(aEnd);
        }

        io_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_UI_REPLACE, NULL);
    };
}
@@ -308,6 +311,22 @@
            SetOtherMarkPos(GetMarkPos());
    }

    void Fieldmark::SetMarkStartPos( const SwPosition& rNewStartPos )
    {
        if ( GetMarkPos( ) <= GetOtherMarkPos( ) )
            return SetMarkPos( rNewStartPos );
        else
            return SetOtherMarkPos( rNewStartPos );
    }

    void Fieldmark::SetMarkEndPos( const SwPosition& rNewEndPos )
    {
        if ( GetMarkPos( ) <= GetOtherMarkPos( ) )
            return SetOtherMarkPos( rNewEndPos );
        else
            return SetMarkPos( rNewEndPos );
    }

    OUString Fieldmark::ToString( ) const
    {
        return "Fieldmark: ( Name, Type, [ Nd1, Id1 ], [ Nd2, Id2 ] ): ( " + m_aName + ", "
@@ -349,7 +368,9 @@

        // For some reason the end mark is moved from 1 by the Insert: we don't
        // want this for checkboxes
        this->GetMarkEnd( ).nContent--;
        SwPosition aNewEndPos = this->GetMarkEnd();
        aNewEndPos.nContent--;
        SetMarkEndPos( aNewEndPos );
    }

    void CheckboxFieldmark::ReleaseDoc(SwDoc* const pDoc)
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index 3cb4dff..d972236 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -828,16 +828,26 @@
            case IDocumentMarkAccess::BOOKMARK:
            case IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK:
            case IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK:
                // if(dynamic_cast<IBookmark*>)
                {
                    IDocumentMarkAccess::iterator_t ppBookmark = lcl_FindMark(m_vBookmarks, *ppMark);
                    OSL_ENSURE(ppBookmark != m_vBookmarks.end(),
                        "<MarkManager::deleteMark(..)>"
                        " - Bookmark not found.");
                    m_vBookmarks.erase(ppBookmark);
                    if ( ppBookmark != m_vBookmarks.end() )
                    {
                        m_vBookmarks.erase(ppBookmark);
                    }
                    else
                    {
                        OSL_ENSURE( false, "<MarkManager::deleteMark(..)> - Bookmark not found in Bookmark container.");
                    }

                    ppBookmark = lcl_FindMark(m_vCommonMarks, *ppMark);
                    m_vCommonMarks.erase(ppBookmark);
                    if ( ppBookmark != m_vCommonMarks.end() )
                    {
                        m_vCommonMarks.erase(ppBookmark);
                    }
                    else
                    {
                        OSL_ENSURE( false, "<MarkManager::deleteMark(..)> - Bookmark not found in common mark container.");
                    }
                }
                break;

@@ -845,22 +855,39 @@
            case IDocumentMarkAccess::CHECKBOX_FIELDMARK:
                {
                    IDocumentMarkAccess::iterator_t ppFieldmark = lcl_FindMark(m_vFieldmarks, *ppMark);
                    OSL_ENSURE(ppFieldmark != m_vFieldmarks.end(),
                        "<MarkManager::deleteMark(..)>"
                        " - Bookmark not found.");
                    m_vFieldmarks.erase(ppFieldmark);
                    ret.reset(new LazyFieldmarkDeleter(*ppMark, m_pDoc));
                    if ( ppFieldmark != m_vFieldmarks.end() )
                    {
                        m_vFieldmarks.erase(ppFieldmark);
                        ret.reset(new LazyFieldmarkDeleter(*ppMark, m_pDoc));
                    }
                    else
                    {
                        OSL_ENSURE( false, "<MarkManager::deleteMark(..)> - Fieldmark not found in Fieldmark container.");
                    }

                    ppFieldmark = lcl_FindMark(m_vCommonMarks, *ppMark);
                    m_vCommonMarks.erase(ppFieldmark);
                    if ( ppFieldmark != m_vCommonMarks.end() )
                    {
                        m_vCommonMarks.erase(ppFieldmark);
                    }
                    else
                    {
                        OSL_ENSURE( false, "<MarkManager::deleteMark(..)> - Fieldmark not found in common mark container.");
                    }
                }
                break;

            case IDocumentMarkAccess::ANNOTATIONMARK:
                {
                    IDocumentMarkAccess::iterator_t ppAnnotationMark = lcl_FindMark(m_vAnnotationMarks, *ppMark);
                    OSL_ENSURE( ppAnnotationMark != m_vAnnotationMarks.end(), "<MarkManager::deleteMark(..)> - Annotation Mark not found." );
                    m_vAnnotationMarks.erase(ppAnnotationMark);
                    if ( ppAnnotationMark != m_vAnnotationMarks.end() )
                    {
                        m_vAnnotationMarks.erase(ppAnnotationMark);
                    }
                    else
                    {
                        OSL_ENSURE( false, "<MarkManager::deleteMark(..)> - Annotation Mark not found in Annotation Mark container.");
                    }
                }
                break;

@@ -869,7 +896,14 @@
            case IDocumentMarkAccess::UNO_BOOKMARK:
                {
                    IDocumentMarkAccess::iterator_t ppOtherMark = lcl_FindMark(m_vCommonMarks, *ppMark);
                    m_vCommonMarks.erase(ppOtherMark);
                    if ( ppOtherMark != m_vCommonMarks.end() )
                    {
                        m_vCommonMarks.erase(ppOtherMark);
                    }
                    else
                    {
                        OSL_ENSURE( false, "<MarkManager::deleteMark(..)> - Navigator Reminder, DDE Mark or Uno Makr not found in common mark container.");
                    }
                }
                break;
        }
@@ -1052,6 +1086,11 @@
        return sTmp;
    }

    void MarkManager::assureSortedMarkContainers() const
    {
        const_cast< MarkManager* >(this)->sortMarks();
    }

    void MarkManager::sortSubsetMarks()
    {
        sort(m_vCommonMarks.begin(), m_vCommonMarks.end(), &lcl_MarkOrderingByStart);
diff --git a/sw/source/core/inc/MarkManager.hxx b/sw/source/core/inc/MarkManager.hxx
index 549d06b..ed4afd7 100644
--- a/sw/source/core/inc/MarkManager.hxx
+++ b/sw/source/core/inc/MarkManager.hxx
@@ -95,6 +95,8 @@
            virtual sal_Int32 getAnnotationMarksCount() const;
            virtual const_iterator_t findAnnotationMark( const ::rtl::OUString& rName ) const;

            virtual void assureSortedMarkContainers() const;

        private:
            // make names
            OUString getUniqueMarkName(const OUString& rName) const;
diff --git a/sw/source/core/inc/bookmrk.hxx b/sw/source/core/inc/bookmrk.hxx
index 761842f..9df8878 100644
--- a/sw/source/core/inc/bookmrk.hxx
+++ b/sw/source/core/inc/bookmrk.hxx
@@ -47,6 +47,7 @@
            : virtual public IMark
        {
        public:
            //getters
            virtual SwPosition& GetMarkPos() const
                { return *m_pPos1; }
            virtual const OUString& GetName() const
@@ -215,6 +216,9 @@

            virtual void ReleaseDoc(SwDoc* const) = 0;

            void SetMarkStartPos( const SwPosition& rNewStartPos );
            void SetMarkEndPos( const SwPosition& rNewEndPos );

            virtual void Invalidate();
            virtual OUString ToString() const;

diff --git a/sw/source/core/inc/crossrefbookmark.hxx b/sw/source/core/inc/crossrefbookmark.hxx
index fa4777b..79212d3 100644
--- a/sw/source/core/inc/crossrefbookmark.hxx
+++ b/sw/source/core/inc/crossrefbookmark.hxx
@@ -36,6 +36,7 @@
                const OUString& rShortName,
                const OUString& rPrefix);

            // getters
            virtual SwPosition& GetOtherMarkPos() const;
            virtual SwPosition& GetMarkStart() const
                { return *m_pPos1; }
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 92d70da..a82bda2 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -1014,6 +1014,7 @@
        }
    }

    bool bSortMarks = false;
    SwIndexReg aTmpIdxReg;
    if ( !bNegative && !bDelete )
    {
@@ -1072,6 +1073,7 @@
                    rPos.GetIndex() == rIdx.GetIndex() )
                {
                    rIdx.Assign( &aTmpIdxReg, rIdx.GetIndex() );
                    bSortMarks = true;
                }
            }
        }
@@ -1090,6 +1092,10 @@
    }

    aTmpIdxReg.MoveTo( *this );
    if ( bSortMarks )
    {
        getIDocumentMarkAccess()->assureSortedMarkContainers();
    }
}

void SwTxtNode::_ChgTxtCollUpdateNum( const SwTxtFmtColl *pOldColl,